<template>
  <div style="width: 400px; margin: 50px auto; text-align: center">
    <h1>Jaguar 授权平台</h1>
    <br />
    <el-divider />
    <div>
      <span style="color: blue; font-size: large; font-weight: bold">
        {{ data.clientName }}</span
      ><span> 希望访问您的帐户</span>
    </div>
    <br />

    <div>上述应用程序请求以下权限，请审阅这些内容，</div>
    <div>如果您同意请提交授权。</div>
    <br />

    <el-form
      v-if="!loading"
      ref="dataForm"
      label-width="auto"
      label-position="right"
    >
      <div v-for="serverInfo in data.serverInfos" :key="serverInfo.serverId">
        <h4>
          {{ serverInfo.serverName }}
        </h4>
        <br />

        <template v-for="scope in serverInfo.scopes" :key="scope.scopeName">
          <el-form-item
            v-if="scope.scopeName != 'openid'"
            :label="scope.scopeLabel"
          >
            <el-switch
              v-model="scope.granted"
              :active-value="true"
              :inactive-value="false"
              active-color="#13ce66"
              inactive-color="#ff4949"
            />
          </el-form-item>
        </template>
      </div>

      <el-button type="primary" @click="submitHandler">提交授权</el-button>
    </el-form>
    <br />
  </div>
</template>
<script>
import { authorize, confirmAccess } from '@/api/oauth2'

export default {
  name: 'OAuth2Authorize',
  props: {
    client_id: {
      type: String,
      required: true,
    },
    response_type: {
      type: String,
      default: 'code',
    },
    redirect_uri: {
      type: String,
      required: true,
    },
    scope: {
      type: String,
      default: '',
    },
    state: {
      type: String,
      default: '',
    },
    code_challenge: {
      type: String,
      default: '',
    },
    code_challenge_method: {
      type: String,
      default: 'S256',
    },
  },
  data() {
    return {
      data: {
        clientName: '',
        serverInfos: {},
        state: '',
      },
      loading: true,
    }
  },
  mounted() {
    this.listScopes()
  },
  methods: {
    listScopes() {
      if (!this.client_id) {
        this.$message.error('参数丢失：client_id')
        return
      }
      if (!this.redirect_uri) {
        this.$message.error('参数丢失：redirect_uri')
        return
      }

      let params = {
        client_id: this.client_id,
        response_type: this.response_type,
        redirect_uri: this.redirect_uri,
        scope: this.scope,
      }
      if (this.state) {
        params.state = this.state
      }

      if (this.code_challenge) {
        params.code_challenge = this.code_challenge
        params.code_challenge_method = this.code_challenge_method
      }

      authorize(params)
        .then((res) => {
          let data = res.data.data
          this.data.clientName = data.clientName
          this.data.state = data.state

          if (data.scope) {
            let serverInfos = data.scope
            for (let i in serverInfos) {
              let serverInfo = serverInfos[i]
              for (let j in serverInfo.scopes) {
                let scope = serverInfo.scopes[j]
                serverInfo.scopes[j] = {
                  scopeName: this.getScopeName(scope),
                  scopeLabel: this.getScopeLabel(scope),
                  granted: true,
                }
              }
            }
            this.data.serverInfos = serverInfos
          }
        })
        .finally(() => {
          this.loading = false
        })
    },
    submitHandler() {
      let grantedScopes = []
      for (let i in this.data.serverInfos) {
        let serverInfo = this.data.serverInfos[i]
        for (let i in serverInfo.scopes) {
          let scope = serverInfo.scopes[i]
          if (!scope.granted || scope.scopeName == 'openid') continue

          grantedScopes.push(scope.scopeName)
        }
      }

      confirmAccess({
        client_id: this.client_id,
        state: this.data.state,
        scope: grantedScopes,
      })
    },
    getScopeName(scope) {
      switch (scope) {
        case 'openid':
        case 'profile':
        case 'email':
        case 'phone':
          return scope
        default:
          return encodeURIComponent(scope)
      }
    },
    getScopeLabel(scope) {
      switch (scope) {
        case 'profile':
          return '个人简介'
        case 'email':
          return '电子邮件'
        case 'phone':
          return '电话'
        default:
          return scope
      }
    },
  },
}
</script>
